//===----------------------------------------------------------------------===//
//
// This source file is part of the Soto for AWS open source project
//
// Copyright (c) 2017-2024 the Soto project authors
// Licensed under Apache License v2.0
//
// See LICENSE.txt for license information
// See CONTRIBUTORS.txt for the list of Soto project authors
//
// SPDX-License-Identifier: Apache-2.0
//
//===----------------------------------------------------------------------===//

// THIS FILE IS AUTOMATICALLY GENERATED by https://github.com/soto-project/soto-codegenerator.
// DO NOT EDIT.

#if canImport(FoundationEssentials)
import FoundationEssentials
#else
import Foundation
#endif
@_exported import SotoCore

/// Service object for interacting with AWS DSQL service.
///
/// This is an interface reference for Amazon Aurora DSQL. It contains documentation for one of the programming or command line interfaces you can use to manage Amazon Aurora DSQL. Amazon Aurora DSQL is a serverless, distributed SQL database suitable for workloads of any size. is available in both single-Region and multi-Region configurations, so your clusters and databases are always available even if an Availability Zone or an Amazon Web Services Region are unavailable.  lets you focus on using your data to acquire new insights for your business and customers.
public struct DSQL: AWSService {
    // MARK: Member variables

    /// Client used for communication with AWS
    public let client: AWSClient
    /// Service configuration
    public let config: AWSServiceConfig

    // MARK: Initialization

    /// Initialize the DSQL client
    /// - parameters:
    ///     - client: AWSClient used to process requests
    ///     - region: Region of server you want to communicate with. This will override the partition parameter.
    ///     - partition: AWS partition where service resides, standard (.aws), china (.awscn), government (.awsusgov).
    ///     - endpoint: Custom endpoint URL to use instead of standard AWS servers
    ///     - middleware: Middleware chain used to edit requests before they are sent and responses before they are decoded 
    ///     - timeout: Timeout value for HTTP requests
    ///     - byteBufferAllocator: Allocator for ByteBuffers
    ///     - options: Service options
    public init(
        client: AWSClient,
        region: SotoCore.Region? = nil,
        partition: AWSPartition = .aws,
        endpoint: String? = nil,
        middleware: AWSMiddlewareProtocol? = nil,
        timeout: TimeAmount? = nil,
        byteBufferAllocator: ByteBufferAllocator = ByteBufferAllocator(),
        options: AWSServiceConfig.Options = []
    ) {
        self.client = client
        self.config = AWSServiceConfig(
            region: region,
            partition: region?.partition ?? partition,
            serviceName: "DSQL",
            serviceIdentifier: "dsql",
            serviceProtocol: .restjson,
            apiVersion: "2018-05-10",
            endpoint: endpoint,
            errorType: DSQLErrorType.self,
            middleware: middleware,
            timeout: timeout,
            byteBufferAllocator: byteBufferAllocator,
            options: options
        )
    }





    // MARK: API Calls

    /// The CreateCluster API allows you to create both single-region clusters and multi-Region clusters. With the addition of the multiRegionProperties parameter, you can create a cluster with witness Region support and establish peer relationships with clusters in other Regions during creation.  Creating multi-Region clusters requires additional IAM permissions beyond those needed for single-Region clusters, as detailed in the Required permissions section below.   Required permissions   dsql:CreateCluster  Required to create a cluster. Resources: arn:aws:dsql:region:account-id:cluster/*   dsql:TagResource  Permission to add tags to a resource. Resources: arn:aws:dsql:region:account-id:cluster/*   dsql:PutMultiRegionProperties  Permission to configure multi-region properties for a cluster. Resources: arn:aws:dsql:region:account-id:cluster/*   dsql:AddPeerCluster  When specifying multiRegionProperties.clusters, permission to add peer clusters. Resources:   Local cluster: arn:aws:dsql:region:account-id:cluster/*    Each peer cluster: exact ARN of each specified peer cluster    dsql:PutWitnessRegion  When specifying multiRegionProperties.witnessRegion, permission to set a witness Region. This permission is checked both in the cluster Region and in the witness Region. Resources: arn:aws:dsql:region:account-id:cluster/*  Condition Keys: dsql:WitnessRegion (matching the specified witness region)      The witness Region specified in multiRegionProperties.witnessRegion cannot be the same as the cluster's Region.
    @Sendable
    @inlinable
    public func createCluster(_ input: CreateClusterInput, logger: Logger = AWSClient.loggingDisabled) async throws -> CreateClusterOutput {
        try await self.client.execute(
            operation: "CreateCluster", 
            path: "/cluster", 
            httpMethod: .POST, 
            serviceConfig: self.config, 
            input: input, 
            logger: logger
        )
    }
    /// The CreateCluster API allows you to create both single-region clusters and multi-Region clusters. With the addition of the multiRegionProperties parameter, you can create a cluster with witness Region support and establish peer relationships with clusters in other Regions during creation.  Creating multi-Region clusters requires additional IAM permissions beyond those needed for single-Region clusters, as detailed in the Required permissions section below.   Required permissions   dsql:CreateCluster  Required to create a cluster. Resources: arn:aws:dsql:region:account-id:cluster/*   dsql:TagResource  Permission to add tags to a resource. Resources: arn:aws:dsql:region:account-id:cluster/*   dsql:PutMultiRegionProperties  Permission to configure multi-region properties for a cluster. Resources: arn:aws:dsql:region:account-id:cluster/*   dsql:AddPeerCluster  When specifying multiRegionProperties.clusters, permission to add peer clusters. Resources:   Local cluster: arn:aws:dsql:region:account-id:cluster/*    Each peer cluster: exact ARN of each specified peer cluster    dsql:PutWitnessRegion  When specifying multiRegionProperties.witnessRegion, permission to set a witness Region. This permission is checked both in the cluster Region and in the witness Region. Resources: arn:aws:dsql:region:account-id:cluster/*  Condition Keys: dsql:WitnessRegion (matching the specified witness region)      The witness Region specified in multiRegionProperties.witnessRegion cannot be the same as the cluster's Region.
    ///
    /// Parameters:
    ///   - clientToken: A unique, case-sensitive identifier that you provide to ensure the idempotency of the request. Idempotency ensures that an API request completes only once. With an idempotent request, if the original request completes successfully, the subsequent retries with the same client token return the result from the original successful request and they have no additional effect. If you don't specify a client token, the Amazon Web Services SDK automatically generates one.
    ///   - deletionProtectionEnabled: If enabled, you can't delete your cluster. You must first disable this property before you can delete your cluster.
    ///   - kmsEncryptionKey: The KMS key that encrypts and protects the data on your cluster. You can specify the ARN, ID, or alias of an existing key or have Amazon Web Services create a default key for you.
    ///   - multiRegionProperties: The configuration settings when creating a multi-Region cluster, including the witness region and linked cluster properties.
    ///   - tags: A map of key and value pairs to use to tag your cluster.
    ///   - logger: Logger use during operation
    @inlinable
    public func createCluster(
        clientToken: String? = CreateClusterInput.idempotencyToken(),
        deletionProtectionEnabled: Bool? = nil,
        kmsEncryptionKey: String? = nil,
        multiRegionProperties: MultiRegionProperties? = nil,
        tags: [String: String]? = nil,
        logger: Logger = AWSClient.loggingDisabled        
    ) async throws -> CreateClusterOutput {
        let input = CreateClusterInput(
            clientToken: clientToken, 
            deletionProtectionEnabled: deletionProtectionEnabled, 
            kmsEncryptionKey: kmsEncryptionKey, 
            multiRegionProperties: multiRegionProperties, 
            tags: tags
        )
        return try await self.createCluster(input, logger: logger)
    }

    /// Deletes a cluster in Amazon Aurora DSQL.
    @Sendable
    @inlinable
    public func deleteCluster(_ input: DeleteClusterInput, logger: Logger = AWSClient.loggingDisabled) async throws -> DeleteClusterOutput {
        try await self.client.execute(
            operation: "DeleteCluster", 
            path: "/cluster/{identifier}", 
            httpMethod: .DELETE, 
            serviceConfig: self.config, 
            input: input, 
            logger: logger
        )
    }
    /// Deletes a cluster in Amazon Aurora DSQL.
    ///
    /// Parameters:
    ///   - clientToken: A unique, case-sensitive identifier that you provide to ensure the idempotency of the request. Idempotency ensures that an API request completes only once. With an idempotent request, if the original request completes successfully. The subsequent retries with the same client token return the result from the original successful request and they have no additional effect. If you don't specify a client token, the Amazon Web Services SDK automatically generates one.
    ///   - identifier: The ID of the cluster to delete.
    ///   - logger: Logger use during operation
    @inlinable
    public func deleteCluster(
        clientToken: String? = DeleteClusterInput.idempotencyToken(),
        identifier: String,
        logger: Logger = AWSClient.loggingDisabled        
    ) async throws -> DeleteClusterOutput {
        let input = DeleteClusterInput(
            clientToken: clientToken, 
            identifier: identifier
        )
        return try await self.deleteCluster(input, logger: logger)
    }

    /// Retrieves information about a cluster.
    @Sendable
    @inlinable
    public func getCluster(_ input: GetClusterInput, logger: Logger = AWSClient.loggingDisabled) async throws -> GetClusterOutput {
        try await self.client.execute(
            operation: "GetCluster", 
            path: "/cluster/{identifier}", 
            httpMethod: .GET, 
            serviceConfig: self.config, 
            input: input, 
            logger: logger
        )
    }
    /// Retrieves information about a cluster.
    ///
    /// Parameters:
    ///   - identifier: The ID of the cluster to retrieve.
    ///   - logger: Logger use during operation
    @inlinable
    public func getCluster(
        identifier: String,
        logger: Logger = AWSClient.loggingDisabled        
    ) async throws -> GetClusterOutput {
        let input = GetClusterInput(
            identifier: identifier
        )
        return try await self.getCluster(input, logger: logger)
    }

    /// Retrieves the VPC endpoint service name.
    @Sendable
    @inlinable
    public func getVpcEndpointServiceName(_ input: GetVpcEndpointServiceNameInput, logger: Logger = AWSClient.loggingDisabled) async throws -> GetVpcEndpointServiceNameOutput {
        try await self.client.execute(
            operation: "GetVpcEndpointServiceName", 
            path: "/clusters/{identifier}/vpc-endpoint-service-name", 
            httpMethod: .GET, 
            serviceConfig: self.config, 
            input: input, 
            logger: logger
        )
    }
    /// Retrieves the VPC endpoint service name.
    ///
    /// Parameters:
    ///   - identifier: The ID of the cluster to retrieve.
    ///   - logger: Logger use during operation
    @inlinable
    public func getVpcEndpointServiceName(
        identifier: String,
        logger: Logger = AWSClient.loggingDisabled        
    ) async throws -> GetVpcEndpointServiceNameOutput {
        let input = GetVpcEndpointServiceNameInput(
            identifier: identifier
        )
        return try await self.getVpcEndpointServiceName(input, logger: logger)
    }

    /// Retrieves information about a list of clusters.
    @Sendable
    @inlinable
    public func listClusters(_ input: ListClustersInput, logger: Logger = AWSClient.loggingDisabled) async throws -> ListClustersOutput {
        try await self.client.execute(
            operation: "ListClusters", 
            path: "/cluster", 
            httpMethod: .GET, 
            serviceConfig: self.config, 
            input: input, 
            logger: logger
        )
    }
    /// Retrieves information about a list of clusters.
    ///
    /// Parameters:
    ///   - maxResults: An optional parameter that specifies the maximum number of results to return. You can use nextToken to display the next page of results.
    ///   - nextToken: If your initial ListClusters operation returns a nextToken, you can include the returned nextToken in following ListClusters operations, which returns results in the next page.
    ///   - logger: Logger use during operation
    @inlinable
    public func listClusters(
        maxResults: Int? = nil,
        nextToken: String? = nil,
        logger: Logger = AWSClient.loggingDisabled        
    ) async throws -> ListClustersOutput {
        let input = ListClustersInput(
            maxResults: maxResults, 
            nextToken: nextToken
        )
        return try await self.listClusters(input, logger: logger)
    }

    /// Lists all of the tags for a resource.
    @Sendable
    @inlinable
    public func listTagsForResource(_ input: ListTagsForResourceInput, logger: Logger = AWSClient.loggingDisabled) async throws -> ListTagsForResourceOutput {
        try await self.client.execute(
            operation: "ListTagsForResource", 
            path: "/tags/{resourceArn}", 
            httpMethod: .GET, 
            serviceConfig: self.config, 
            input: input, 
            logger: logger
        )
    }
    /// Lists all of the tags for a resource.
    ///
    /// Parameters:
    ///   - resourceArn: The ARN of the resource for which you want to list the tags.
    ///   - logger: Logger use during operation
    @inlinable
    public func listTagsForResource(
        resourceArn: String,
        logger: Logger = AWSClient.loggingDisabled        
    ) async throws -> ListTagsForResourceOutput {
        let input = ListTagsForResourceInput(
            resourceArn: resourceArn
        )
        return try await self.listTagsForResource(input, logger: logger)
    }

    /// Tags a resource with a map of key and value pairs.
    @Sendable
    @inlinable
    public func tagResource(_ input: TagResourceInput, logger: Logger = AWSClient.loggingDisabled) async throws {
        try await self.client.execute(
            operation: "TagResource", 
            path: "/tags/{resourceArn}", 
            httpMethod: .POST, 
            serviceConfig: self.config, 
            input: input, 
            logger: logger
        )
    }
    /// Tags a resource with a map of key and value pairs.
    ///
    /// Parameters:
    ///   - resourceArn: The ARN of the resource that you want to tag.
    ///   - tags: A map of key and value pairs to use to tag your resource.
    ///   - logger: Logger use during operation
    @inlinable
    public func tagResource(
        resourceArn: String,
        tags: [String: String],
        logger: Logger = AWSClient.loggingDisabled        
    ) async throws {
        let input = TagResourceInput(
            resourceArn: resourceArn, 
            tags: tags
        )
        return try await self.tagResource(input, logger: logger)
    }

    /// Removes a tag from a resource.
    @Sendable
    @inlinable
    public func untagResource(_ input: UntagResourceInput, logger: Logger = AWSClient.loggingDisabled) async throws {
        try await self.client.execute(
            operation: "UntagResource", 
            path: "/tags/{resourceArn}", 
            httpMethod: .DELETE, 
            serviceConfig: self.config, 
            input: input, 
            logger: logger
        )
    }
    /// Removes a tag from a resource.
    ///
    /// Parameters:
    ///   - resourceArn: The ARN of the resource from which to remove tags.
    ///   - tagKeys: The array of keys of the tags that you want to remove.
    ///   - logger: Logger use during operation
    @inlinable
    public func untagResource(
        resourceArn: String,
        tagKeys: [String],
        logger: Logger = AWSClient.loggingDisabled        
    ) async throws {
        let input = UntagResourceInput(
            resourceArn: resourceArn, 
            tagKeys: tagKeys
        )
        return try await self.untagResource(input, logger: logger)
    }

    /// The UpdateCluster API allows you to modify both single-Region and multi-Region cluster configurations. With the multiRegionProperties parameter, you can add or modify witness Region support and manage peer relationships with clusters in other Regions.  Note that updating multi-region clusters requires additional IAM permissions beyond those needed for standard cluster updates, as detailed in the Permissions section.   Required permissions   dsql:UpdateCluster  Permission to update a DSQL cluster. Resources: arn:aws:dsql:region:account-id:cluster/cluster-id      dsql:PutMultiRegionProperties  Permission to configure multi-Region properties for a cluster. Resources: arn:aws:dsql:region:account-id:cluster/cluster-id      dsql:GetCluster  Permission to retrieve cluster information. Resources: arn:aws:dsql:region:account-id:cluster/cluster-id    dsql:AddPeerCluster  Permission to add peer clusters. Resources:   Local cluster: arn:aws:dsql:region:account-id:cluster/cluster-id     Each peer cluster: exact ARN of each specified peer cluster    dsql:RemovePeerCluster  Permission to remove peer clusters. The dsql:RemovePeerCluster permission uses a wildcard ARN pattern to simplify permission management during updates. Resources: arn:aws:dsql:*:account-id:cluster/*     dsql:PutWitnessRegion  Permission to set a witness Region. Resources: arn:aws:dsql:region:account-id:cluster/cluster-id   Condition Keys: dsql:WitnessRegion (matching the specified witness Region)  This permission is checked both in the cluster Region and in the witness Region.       The witness region specified in multiRegionProperties.witnessRegion cannot be the same as the cluster's Region.   When updating clusters with peer relationships, permissions are checked for both adding and removing peers.   The dsql:RemovePeerCluster permission uses a wildcard ARN pattern to simplify permission management during updates.
    @Sendable
    @inlinable
    public func updateCluster(_ input: UpdateClusterInput, logger: Logger = AWSClient.loggingDisabled) async throws -> UpdateClusterOutput {
        try await self.client.execute(
            operation: "UpdateCluster", 
            path: "/cluster/{identifier}", 
            httpMethod: .POST, 
            serviceConfig: self.config, 
            input: input, 
            logger: logger
        )
    }
    /// The UpdateCluster API allows you to modify both single-Region and multi-Region cluster configurations. With the multiRegionProperties parameter, you can add or modify witness Region support and manage peer relationships with clusters in other Regions.  Note that updating multi-region clusters requires additional IAM permissions beyond those needed for standard cluster updates, as detailed in the Permissions section.   Required permissions   dsql:UpdateCluster  Permission to update a DSQL cluster. Resources: arn:aws:dsql:region:account-id:cluster/cluster-id      dsql:PutMultiRegionProperties  Permission to configure multi-Region properties for a cluster. Resources: arn:aws:dsql:region:account-id:cluster/cluster-id      dsql:GetCluster  Permission to retrieve cluster information. Resources: arn:aws:dsql:region:account-id:cluster/cluster-id    dsql:AddPeerCluster  Permission to add peer clusters. Resources:   Local cluster: arn:aws:dsql:region:account-id:cluster/cluster-id     Each peer cluster: exact ARN of each specified peer cluster    dsql:RemovePeerCluster  Permission to remove peer clusters. The dsql:RemovePeerCluster permission uses a wildcard ARN pattern to simplify permission management during updates. Resources: arn:aws:dsql:*:account-id:cluster/*     dsql:PutWitnessRegion  Permission to set a witness Region. Resources: arn:aws:dsql:region:account-id:cluster/cluster-id   Condition Keys: dsql:WitnessRegion (matching the specified witness Region)  This permission is checked both in the cluster Region and in the witness Region.       The witness region specified in multiRegionProperties.witnessRegion cannot be the same as the cluster's Region.   When updating clusters with peer relationships, permissions are checked for both adding and removing peers.   The dsql:RemovePeerCluster permission uses a wildcard ARN pattern to simplify permission management during updates.
    ///
    /// Parameters:
    ///   - clientToken: A unique, case-sensitive identifier that you provide to ensure the idempotency of the request. Idempotency ensures that an API request completes only once. With an idempotent request, if the original request completes successfully. The subsequent retries with the same client token return the result from the original successful request and they have no additional effect. If you don't specify a client token, the Amazon Web Services SDK automatically generates one.
    ///   - deletionProtectionEnabled: Specifies whether to enable deletion protection in your cluster.
    ///   - identifier: The ID of the cluster you want to update.
    ///   - kmsEncryptionKey: The KMS key that encrypts and protects the data on your cluster. You can specify the ARN, ID, or alias of an existing key or have Amazon Web Services create a default key for you.
    ///   - multiRegionProperties: The new multi-Region cluster configuration settings to be applied during an update operation.
    ///   - logger: Logger use during operation
    @inlinable
    public func updateCluster(
        clientToken: String? = UpdateClusterInput.idempotencyToken(),
        deletionProtectionEnabled: Bool? = nil,
        identifier: String,
        kmsEncryptionKey: String? = nil,
        multiRegionProperties: MultiRegionProperties? = nil,
        logger: Logger = AWSClient.loggingDisabled        
    ) async throws -> UpdateClusterOutput {
        let input = UpdateClusterInput(
            clientToken: clientToken, 
            deletionProtectionEnabled: deletionProtectionEnabled, 
            identifier: identifier, 
            kmsEncryptionKey: kmsEncryptionKey, 
            multiRegionProperties: multiRegionProperties
        )
        return try await self.updateCluster(input, logger: logger)
    }
}

extension DSQL {
    /// Initializer required by `AWSService.with(middlewares:timeout:byteBufferAllocator:options)`. You are not able to use this initializer directly as there are not public
    /// initializers for `AWSServiceConfig.Patch`. Please use `AWSService.with(middlewares:timeout:byteBufferAllocator:options)` instead.
    public init(from: DSQL, patch: AWSServiceConfig.Patch) {
        self.client = from.client
        self.config = from.config.with(patch: patch)
    }
}

// MARK: Paginators

@available(macOS 10.15, iOS 13.0, tvOS 13.0, watchOS 6.0, *)
extension DSQL {
    /// Return PaginatorSequence for operation ``listClusters(_:logger:)``.
    ///
    /// - Parameters:
    ///   - input: Input for operation
    ///   - logger: Logger used for logging
    @inlinable
    public func listClustersPaginator(
        _ input: ListClustersInput,
        logger: Logger = AWSClient.loggingDisabled
    ) -> AWSClient.PaginatorSequence<ListClustersInput, ListClustersOutput> {
        return .init(
            input: input,
            command: self.listClusters,
            inputKey: \ListClustersInput.nextToken,
            outputKey: \ListClustersOutput.nextToken,
            logger: logger
        )
    }
    /// Return PaginatorSequence for operation ``listClusters(_:logger:)``.
    ///
    /// - Parameters:
    ///   - maxResults: An optional parameter that specifies the maximum number of results to return. You can use nextToken to display the next page of results.
    ///   - logger: Logger used for logging
    @inlinable
    public func listClustersPaginator(
        maxResults: Int? = nil,
        logger: Logger = AWSClient.loggingDisabled        
    ) -> AWSClient.PaginatorSequence<ListClustersInput, ListClustersOutput> {
        let input = ListClustersInput(
            maxResults: maxResults
        )
        return self.listClustersPaginator(input, logger: logger)
    }
}

extension DSQL.ListClustersInput: AWSPaginateToken {
    @inlinable
    public func usingPaginationToken(_ token: String) -> DSQL.ListClustersInput {
        return .init(
            maxResults: self.maxResults,
            nextToken: token
        )
    }
}

// MARK: Waiters

@available(macOS 10.15, iOS 13.0, tvOS 13.0, watchOS 6.0, *)
extension DSQL {
    /// Waiter for operation ``getCluster(_:logger:)``.
    ///
    /// - Parameters:
    ///   - input: Input for operation
    ///   - logger: Logger used for logging
    @inlinable
    public func waitUntilClusterActive(
        _ input: GetClusterInput,
        maxWaitTime: TimeAmount? = nil,
        logger: Logger = AWSClient.loggingDisabled
    ) async throws {
        let waiter = AWSClient.Waiter<GetClusterInput, _>(
            acceptors: [
                .init(state: .success, matcher: try! JMESPathMatcher("status", expected: "ACTIVE")),
            ],
            command: self.getCluster
        )
        return try await self.client.waitUntil(input, waiter: waiter, maxWaitTime: maxWaitTime, logger: logger)
    }
    /// Waiter for operation ``getCluster(_:logger:)``.
    ///
    /// - Parameters:
    ///   - identifier: The ID of the cluster to retrieve.
    ///   - logger: Logger used for logging
    @inlinable
    public func waitUntilClusterActive(
        identifier: String,
        logger: Logger = AWSClient.loggingDisabled        
    ) async throws {
        let input = GetClusterInput(
            identifier: identifier
        )
        try await self.waitUntilClusterActive(input, logger: logger)
    }

    /// Waiter for operation ``getCluster(_:logger:)``.
    ///
    /// - Parameters:
    ///   - input: Input for operation
    ///   - logger: Logger used for logging
    @inlinable
    public func waitUntilClusterNotExists(
        _ input: GetClusterInput,
        maxWaitTime: TimeAmount? = nil,
        logger: Logger = AWSClient.loggingDisabled
    ) async throws {
        let waiter = AWSClient.Waiter<GetClusterInput, _>(
            acceptors: [
                .init(state: .success, matcher: AWSErrorCodeMatcher("ResourceNotFoundException")),
            ],
            command: self.getCluster
        )
        return try await self.client.waitUntil(input, waiter: waiter, maxWaitTime: maxWaitTime, logger: logger)
    }
    /// Waiter for operation ``getCluster(_:logger:)``.
    ///
    /// - Parameters:
    ///   - identifier: The ID of the cluster to retrieve.
    ///   - logger: Logger used for logging
    @inlinable
    public func waitUntilClusterNotExists(
        identifier: String,
        logger: Logger = AWSClient.loggingDisabled        
    ) async throws {
        let input = GetClusterInput(
            identifier: identifier
        )
        try await self.waitUntilClusterNotExists(input, logger: logger)
    }
}
